home *** CD-ROM | disk | FTP | other *** search
- /* PCXFILE.c - Routines to generate PCX files
- */
-
-
- #include <stdio.h>
- #include "lib.h"
- #include "pcx.h"
-
-
- /* PCX_GETC
-
- Read the next "token" in the picture file. If the high order
- two bits are not 11, then it's a single byte. If they are,
- it's a repeat count, and the next byte is the value to repeat.
- */
-
- int pcx_getc( c, n, fp, maxn )
- FILE *fp;
- uint *c, *n, maxn;
- {
- static int csave=-1, nsave=-1;
- unsigned int i;
-
- if ( !fp )
- return nsave = csave = -1;
-
- if ( nsave == -1 )
- { *n = 1;
-
- if ( (i=getc(fp)) == EOF )
- return ERROR;
-
- if ( (i & 0xc0) == 0xc0 )
- { *n = i & 0x3f;
- if ( (i=getc(fp)) == EOF )
- return ERROR;
- };
-
- *c = i;
- } else
- { *n = nsave;
- *c = csave;
- nsave = csave = -1;
- };
-
- if ( *n > maxn )
- { nsave = *n - maxn;
- csave = *c;
- *n = maxn;
- };
- return OK;
- }
-
-
- /* PCX_PUTC
-
- Write a "token" to the picture file. If the repeat count is
- not 1, then write the repeat count | 0xc0 as the first byte,
- then the character as the next. If the character has its two
- high order bits set, then first write out a repeat count of
- 1, then the character.
-
- pcx_xputc() counts the number of times that it receives a
- character, then passes that information on to pcx_putc().
- */
-
- int pcx_xputc( c, fp )
- FILE *fp;
- int c;
- {
- int i;
- static int csave = -1, n = -1;
-
- if ( c == -1 )
- { if ( csave != -1 )
- if ( pcx_putc( csave, n, fp ) )
- return ERROR;
- csave = n = -1;
- return OK;
- };
-
- if ( c == csave )
- { n++;
- return OK;
- };
-
- if ( csave != -1 )
- { if ( i = pcx_putc( csave, n, fp ) )
- return i;
- csave = n = -1;
- };
-
- csave = c;
- n = 1;
- return OK;
- }
-
-
- int pcx_putc( c, n, fp )
- FILE *fp;
- unsigned int c, n;
- {
- if ( (n > 1) || ( (c & 0xc0) == 0xc0 ) )
- { while ( n > 0x3f )
- if ( pcx_putc( c, 0x3f, fp ) )
- return ERROR;
- else n -= 0x3f;
-
- if ( !n )
- return OK;
-
- if ( fputc( 0xc0 | n, fp ) == EOF )
- return ERROR;
- };
-
- if ( fputc( c, fp ) == EOF )
- return ERROR;
-
- return OK;
- }
-
-
- int pcx_read_pic( pic, fp )
- FILE *fp;
- PCXPIC *pic;
- {
- /* A picture consists of a number of lines, each line having
- a number of planes. Each plane is a bit map.
- */
- uchar *calloc(), *allocz(), *p;
- int i, j, c, n, row, plane, bytes, nrows, nplan;
- PCXHDR *ph;
-
- ph = & pic->hdr;
-
- fseek( fp, 0l, 0 );
- if ( fread( (char *)ph, sizeof(*ph), 1, fp ) != sizeof(*ph) )
- return ERROR;
-
- pcx_getc( (uint *)0, (uint *)0, (FILE *)0, 0 );
-
- bytes = ph->bpl;
- nrows = ph->y2 - ph->y1 +1;
- nplan = ph->nplanes;
-
- for ( plane = 0; plane < nplan; plane++ )
- if ( ! pic->rows[plane] )
- if ( ! (pic->rows[plane] =
- (uchar **)calloc(1,sizeof(char *) * nrows)) )
- return 1;
-
- for ( row = 0; row < nrows; row++ )
- for ( plane = 0; plane < nplan; plane++ )
- { if ( !(p = pic->rows[plane][row]) )
- if ( !(p = pic->rows[plane][row] = calloc(1,bytes +1)) )
- return 1;
-
- for ( n=i=0; i<bytes; i += n )
- { if ( pcx_getc( (uint *)&c, (uint *)&n, (FILE *)fp, bytes - i ) )
- return ERROR;
- for ( j=0; j < n; j++ )
- *p++ = c;
- };
- };
-
- return OK;
- }
-
-
- int pcx_write_pic( pic, fp )
- PCXPIC *pic;
- FILE *fp;
- {
- unsigned char *p;
- int i, row, plane, bytes, nrows, nplan;
-
- fseek( fp, 0l, 0 );
- if ( fwrite( (char *)&(pic->hdr), sizeof(pic->hdr), 1, fp ) != 1 )
- return ERROR;
-
- bytes = pic->hdr.bpl;
- nrows = pic->hdr.y2 - pic->hdr.y1 +1;
- nplan = pic->hdr.nplanes;
-
- for ( row = 0; row < nrows; row++ )
- for ( plane = 0; plane < nplan; plane++, pcx_xputc(-1,fp) )
- for ( p = pic->rows[plane][row], i=bytes; i--; )
- if ( pcx_xputc( *p++, fp ) )
- return ERROR;
-
- pcx_xputc( -1, fp );
- return OK;
- }
-
-
-